Building Logical Entity Data Services
This page last changed on Nov 28, 2008.
Oracle Data Service Integrator Documentation > Data Services Developer's Guide Building Logical Entity Data ServicesThis topic introduces you to logical entity data services. The Benefits of Logical ServicesThe benefit of data services is the ability to combine multiple data sources of different types into service-oriented architectures. Enterprise data is often stored in relational databases, non-relational databases, packaged applications (such as SAP, PeopleSoft, Siebel, and others), custom applications, or files of various types. You might also be accessing data from web services. The goal is to create a new loosely coupled architecture by piecing together the data assets you already have. In a practical sense, this means combining data from relational data sources, web services, XML files, other files, or Java functions. Logical data services are of two types, entity and library. Logical entity services allow you to design, model, and create a data view from many underlying data sources. Logical library services are simply a collection of related functions and procedures within a data service container. This topic introduces logical entity services. On a tangible level, a logical entity service is an XQuery source file with functions and procedures that act on data. A logical entity service has:
In addition, a logical entity service must have a primary read function if you want the service to have an update map. Design ViewLogical data services have their foundation in XML web services. The backbone of a logical data service is its return type, which is a combination of data you design expressed as an XML schema. You can see the return type in the Overview tab in Workshop for WebLogic. Design View of a Logical Data ServiceThe logical service's return type is shown in the center. You can right-click it to see the XML schema source. On the left, you see the defined for the service. On the right, you see other data services that underly the logical data service.
The underlying data services can be physical or logical. The beauty of a logical data service is that a return type is a model. Logical models capture the complexity of data integration once, and allow you to write clients that remain the same even when underlying physical data sources change. The structure of a return type does not need to match the structure of the underlying data sources. Here, the CUSTOMER element has a 1-to-many relationship with its child element ADDRESS, and a 1-to-1 relationship with its other child element, CREDITRATING. Each complex element represents a separate physical data source. The Return Type Schema<?xml version="1.0" encoding="UTF-8" ?> <xs:schema targetNamespace="ld:logical/CustomerProfile" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="CUSTOMER_PROFILE"> <xs:complexType> <xs:sequence> <xs:element name="CUSTOMER"> <xs:complexType> <xs:sequence> <xs:element name="CUSTOMER_ID" type="xs:string"/> <xs:element name="FIRST_NAME" type="xs:string"/> <xs:element name="LAST_NAME" type="xs:string"/> <xs:element name="EMAIL_ADDRESS" type="xs:string"/> <xs:element name="ADDRESS" maxOccurs="unbounded"> <xs:complexType> <xs:sequence> <xs:element name="ADDR_ID" type="xs:string"/> <xs:element name="CUSTOMER_ID" type="xs:string"/> <xs:element name="STREET_ADDRESS1" type="xs:string"/> <xs:element name="STREET_ADDRESS2" type="xs:string" minOccurs="0"/> <xs:element name="CITY" type="xs:string"/> <xs:element name="STATE" type="xs:string"/> <xs:element name="ZIPCODE" type="xs:string"/> <xs:element name="COUNTRY" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="CREDITRATING" maxOccurs="1"> <xs:complexType> <xs:sequence> <xs:element name="CUSTOMER_ID" type="xs:string"/> <xs:element name="RATING" type="xs:int" minOccurs="0"/> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> However, this structure is only by design. You could also have designed the return type with fewer elements, or in a flat structure, depending on how you want the service to return data. The Primary Read FunctionThe functions and procedures in a logical entity service are implemented in XQuery, which queries XML data much as SQL queries relational data. You can get information about any function or procedure by right-clicking it in the Overview tab. A read function, for example, often takes no parameters and returns an instance of the return type. Viewing the Signature of a Read FunctionIn a logical entity service, you can designate one read function as primary. A primary read function captures the main data integration logic in the service. Oracle Data Service Integrator generates the create, update, and delete procedures and the update map from the primary read function. You can see the source code of the primary read function in the Source tab. Checking the Primary Read Function Sourcedeclare function tns:read() as element(tns:CUSTOMER_PROFILE)*{ for $CUSTOMER in cus1:CUSTOMER() return <tns:CUSTOMER_PROFILE> <CUSTOMER> <CUSTOMER_ID>{fn:data($CUSTOMER/CUSTOMER_ID)}</CUSTOMER_ID> <FIRST_NAME>{fn:data($CUSTOMER/FIRST_NAME)}</FIRST_NAME> <LAST_NAME>{fn:data($CUSTOMER/LAST_NAME)}</LAST_NAME> <EMAIL_ADDRESS>{fn:data($CUSTOMER/EMAIL_ADDRESS)}</EMAIL_ADDRESS> { for $ADDRESS in add:ADDRESS() where $CUSTOMER/CUSTOMER_ID eq $ADDRESS/CUSTOMER_ID return <ADDRESS> <ADDR_ID>{fn:data($ADDRESS/ADDR_ID)}</ADDR_ID> <CUSTOMER_ID>{fn:data($ADDRESS/CUSTOMER_ID)}</CUSTOMER_ID> <STREET_ADDRESS1>{fn:data($ADDRESS/STREET_ADDRESS1)}</STREET_ADDRESS1> <STREET_ADDRESS2?>{fn:data($ADDRESS/STREET_ADDRESS2)}</STREET_ADDRESS2> <CITY>{fn:data($ADDRESS/CITY)}</CITY> <STATE>{fn:data($ADDRESS/STATE)}</STATE> <ZIPCODE>{fn:data($ADDRESS/ZIPCODE)}</ZIPCODE> <COUNTRY>{fn:data($ADDRESS/COUNTRY)}</COUNTRY> </ADDRESS> } { for $CREDITRATING in cre:CREDITRATING() where $CUSTOMER/CUSTOMER_ID eq $CREDITRATING/CUSTOMER_ID return <CREDITRATING> <CUSTOMER_ID>{fn:data($CREDITRATING/CUSTOMER_ID)}</CUSTOMER_ID> <RATING?>{fn:data($CREDITRATING/RATING)}</RATING> </CREDITRATING> } </CUSTOMER> </tns:CUSTOMER_PROFILE> }; This read function returns a CUSTOMER_PROFILE element with a nested CUSTOMER element. Each CUSTOMER element has some number of ADDRESS elements and some number of CREDITRATING elements, where the CUSTOMER_ID in ADDRESS or CREDITRATING matches the CUSTOMER_ID in CUSTOMER. (The XQuery where clauses create table joins; see Add a Where Clause to a Query). Create, Update, and Delete ProceduresA logical entity service also typically has create, update, and delete procedures that act on underlying data sources. (The difference between a function and a procedure is that a procedure can have side effects, while a function cannot; see Data Service Types and Functions). The CustomerProfile service has one create procedure, one update procedure, and two delete procedures. It also has a library procedure named stringToShort, which casts between two data types. Viewing Functions and ProceduresQuery Map ViewThe Query Map view maps elements in data sources to the return type. Mapping Data Sources to the Return TypeYou can see the data sources on the left and the return type on the right. The blue lines map elements from the data sources to elements in the return type, showing how the return type receives data. The green dashed lines between the data source blocks create joins, which become where clauses in the XQuery source, for example: for $ADDRESS in add:ADDRESS() where $CUSTOMER/CUSTOMER_ID eq $ADDRESS/CUSTOMER_ID return If you click a data element (not a container element) in the return type, you see its XQuery expression in the expression editor. Mapping Data in an XQuery ExpressionNotice that the mapping expressions use the built-in XQuery function fn:data, which extracts the data value from an XML element. As you map elements visually in the Query Map, Oracle Data Service Integrator creates XQuery source (for example, the read function shown above). The XQuery source is later converted to SQL queries, which you can see in Plan view. Viewing a SQL Query in Plan ViewIn this query plan, you see the left outer join between the CUSTOMER and ADDRESS relational tables. This was created by the green dashed line drawn between the Customer and Address blocks in Query Map view. When you build XQuery functions and procedures visually in Query Map view or by editing in Source view, you can test and run them on an Oracle Data Service Integrator server. During server runtime, the functions and procedures are compiled into an executable query plan. Examine the query plan before you finalize the queries. Query Plan view gives you a peek into a query's execution logic and flags potential performance and memory problems. Building XQuery functions is an iterative process of test, view plan, and edit. Update Map ViewWhile Query Map view shows how a service reads from data sources, Update Map view shows how the service writes data to them. Checking Update Map ViewThe data sources are on the left, with updates coming from the return type on the right. The return type is available to client applications, where users update data. The blocks on the left are update blocks. Each mapped element in an update block has an XQuery expression that defines how the element is updated. You can see the expression in the expression editor below the mapping area. Viewing an XQuery Update ExpressionOracle Data Service Integrator generates the update map for you when you create a logical data service under these conditions:
(If you are using other data source types, you must edit the update template.) You can then customize the update map and test it in Test view, without programming. An application client uses the Service Data Objects programming model to update data sources. SDO is an application framework that allows you to update data sources while disconnected from them, using a flexible, optimistic concurrency model. You use only one API, the SDO API, to update multiple data sources -- relational, web service, XML files, and so on. Test ViewThe Test view available in Workshop for WebLogic works like a built-in client where you can easily test any function or procedure in the data service, before you build a custom client. Choosing a Function or Procedure to TestTesting a read function, for example, returns data as the service would to a client, in the shape of the return type. Reading Customer Profile DataTo test a simple update, click the Edit button, edit some data in the result, then click Submit. When you test the read function again, the results show the change. You can also test an SDO update by submitting a datagraph with a change summary (see Test an Update Procedure). See AlsoConceptsHow TosReferenceOther Sources
|
![]() |
Document generated by Confluence on Jan 13, 2009 15:57 |